package com.example.jpa.service.impl;

import com.example.jpa.entity.Programmer;
import com.example.jpa.repository.ProgrammerRepository;
import com.example.jpa.service.ProgrammerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.Predicate;
import java.util.List;

@Service
public class ProgrammerServiceImpl implements ProgrammerService {

    @Autowired
    private ProgrammerRepository programmerRepository;

    @Override
    public Programmer save(Programmer programmer) {
        return programmerRepository.save(programmer);
    }

    @Override
    public List<Programmer> getList(Programmer programmer) {

        /*
        * 1.findAll(Specification spec):该查询方法需要一个Specification接口实例(规则实例)
        * 2.Specification接口有一个待实现的方法，用来创建Predicate接口实例（条件实例）
        * 3.Predicate接口需要一个Expression的集合（表达式）
        * 4.Expression实例需要使用criteriaBuilder（标准建造者）构建，
        *       1>使用root来获取字段 2>给定对应的查询参数 3>指定查询方式(如equal等)
        *
        * */
        //select * from programmer where name like ? and sex = ?
        //当name和sex都为空，用1=1代替
//        Specification<Programmer> specification = (root,query,criteriaBuilder)->{
//                //1.创建一个初始条件对象
//                // conjunction:当predicate查询条件为空时，使用1=1来代替
//                Predicate predicate = criteriaBuilder.conjunction();
//                // disjunction:当predicate查询条件为空时，使用0=1来代替
//                //Predicate predicate = criteriaBuilder.disjunction();
//
//                //2.如果用户名不为空，则增加查询条件
//                if(!StringUtils.isEmpty(programmer.getName())){
//                    predicate.getExpressions().add(criteriaBuilder.like(root.get("name"),"%" + programmer.getName() + "%"));
//                }
//
//                //3.如果性别不为空，增加查询条件
//                if(programmer.getSex() != null){
//                    predicate.getExpressions().add(criteriaBuilder.equal(root.get("sex"),programmer.getSex()));
//
//                }
//                return predicate;
//        };
        //select * from programmer where name like ? or sex=?
//        Specification<Programmer> specification = (root,query,criteriaBuilder)->{
//            //条件1
//            Predicate predicate1 = criteriaBuilder.disjunction();
//
//            if(!StringUtils.isEmpty(programmer.getName())){
//                predicate1.getExpressions().add(criteriaBuilder.like(root.get("name"),"%" + programmer.getName() + "%"));
//            }
//            //条件2
//            Predicate predicate2 = criteriaBuilder.disjunction();
//            if(programmer.getSex() != null){
//                predicate1.getExpressions().add(criteriaBuilder.equal(root.get("sex"),programmer.getSex()));
//            }
//
//            return criteriaBuilder.or(predicate1,predicate2);
//        };
//        return programmerRepository.findAll(specification);
//    }
        //规则1
        Specification<Programmer> specification1 = (root,query,criteriaBuilder)->{
            Predicate predicate = criteriaBuilder.disjunction();
            if(!StringUtils.isEmpty(programmer.getName())){
                predicate.getExpressions().add(criteriaBuilder.like(root.get("name"),"%" + programmer.getName() + "%"));
            }
            return predicate;
        };
        //规则2
        Specification<Programmer> specification2 = (root,query,criteriaBuilder)->{
            Predicate predicate = criteriaBuilder.disjunction();
            if(programmer.getSex() != null){
                predicate.getExpressions().add(criteriaBuilder.equal(root.get("sex"),programmer.getSex()));
            }
            return predicate;
        };
        //规则3
        Specification<Programmer> specification3 = (root,query,criteriaBuilder)->{
            Predicate predicate = criteriaBuilder.disjunction();
            if(programmer.getStartDate() != null && programmer.getEndDate() != null){
                predicate.getExpressions().add(criteriaBuilder.between(root.get("birthday"),programmer.getStartDate(),programmer.getEndDate()));
            }
            return predicate;
        };
        return programmerRepository.findAll(Specification.where(specification1).or(specification2).or(specification3));

    }

    @Override
    public Programmer update(Programmer programmer) {
        //jap的save方法，如果有id，就会采用update
        return programmerRepository.save(programmer);
    }

    @Override
    public void deleteByIds(List<Long> ids) {

        Specification<Programmer> specification=(root,query,criteriaBuilder) ->{
            Predicate predicate = criteriaBuilder.disjunction();
            if(!CollectionUtils.isEmpty(ids)){
                predicate.getExpressions().add(criteriaBuilder.in(root.get("id")).value(ids));
            }
            return predicate;
        };

        List<Programmer> list = programmerRepository.findAll(specification);
        programmerRepository.deleteAll(list);

    }

//    @Override
//    public Programmer deleteById(Long id) {
//        Optional<Programmer> optional = programmerRepository.findById(id);
//        programmerRepository.deleteById(id);
//        //return optional.orElseThrow(() -> new RuntimeException("你要删除的用户不存在"));
//        return optional.orElse(new Programmer());
//    }

    @Override
    public Programmer findById(Long id) {
        return programmerRepository.findById(id).orElse(new Programmer());
    }
}
